#include "localInfo.h"
#include <QFile>
#include <QFileInfo>
#include <QDebug>
#include <QNetworkInterface>
#include <QStorageInfo>

LocalInfoStruct LocalInfo::sm_localInfoStruct = {"","","","","","","","",""};
bool LocalInfo::readyFlag = false;
bool LocalInfo::cpuInfoReadyFlag = false;
bool LocalInfo::hardDiskInfoReadyFlag = false;
bool LocalInfo::displayCardInfoReadyFlag = false;
bool LocalInfo::netCardInfoReadyFlag = false;
bool LocalInfo::macInfoReadyFlag = false;
bool LocalInfo::lspciInfoReadyFlag = false;
bool LocalInfo::dpkgInfoReadyFlag = false;

LocalInfo::LocalInfo(QObject *parent) : QObject(parent),
    numOfDisk(0),numOfDisplayCard(0)
{
    this->setParent(parent);
    localInfoProcess = new QProcess();
}
LocalInfo::~LocalInfo()
{
    localInfoProcess->terminate();
    if(!localInfoProcess->waitForFinished(3000))
    {
        localInfoProcess->deleteLater();
    }
}

void LocalInfo::getLocalInfo()
{
    qDebug() << "开始获取本机信息！";
    getServiceKey();
}

void LocalInfo::getServiceKey()
{
    qDebug() << "getServiceKey函数中：";
    QFile* kyinfo = new QFile("/etc/.kyinfo");
    QByteArray kyinfoText;
    if (kyinfo)
    {
      if(kyinfo->open(QIODevice::ReadOnly))
      {
          while(!kyinfo->atEnd())
          {
              kyinfoText = kyinfo->readLine();
              QString tempString = QString(kyinfoText);
              if(tempString.contains("servicekey") && !kyinfo->atEnd())
              {
                  sm_localInfoStruct.serviceKey = QString(kyinfo->readLine());
                  break;
              }
          }
      }
      kyinfo->close();
    }
    else
    {
        sm_localInfoStruct.serviceKey = "kyinfo文件不存在";
    }
    delete kyinfo;
    if(sm_localInfoStruct.serviceKey.isEmpty())
    {
        sm_localInfoStruct.serviceKey = "未读取到客户服务序列号";
        qDebug() << "未读取到客户服务序列号";
    }
    else
    {
        qDebug() << "客户服务序列号为" << sm_localInfoStruct.serviceKey;
    }

    getCpuInfo();
}

void LocalInfo::getCpuInfo()
{
    qDebug() << "getCpuInfo函数中!";
    QString arch = QSysInfo::buildCpuArchitecture();
    sm_localInfoStruct.cpuInfo.append(arch);
    cpuInfoReadyFlag = true;
    getHardDiskInfo();
}

void LocalInfo::getHardDiskInfo()
{
    qDebug() << "getHardDiskInfo函数中!";
    QStorageInfo storage = QStorageInfo::root();
    sm_localInfoStruct.installHardDiskInfo.append("<br\>");
    sm_localInfoStruct.installHardDiskInfo.append("root分区位于：");
    sm_localInfoStruct.installHardDiskInfo.append(storage.rootPath());
    sm_localInfoStruct.installHardDiskInfo.append("<br\>");
    sm_localInfoStruct.installHardDiskInfo.append("设备名为：");
    sm_localInfoStruct.installHardDiskInfo.append(QString(storage.device()));
    sm_localInfoStruct.installHardDiskInfo.append("<br\>");
    sm_localInfoStruct.installHardDiskInfo.append("分区格式为：");
    sm_localInfoStruct.installHardDiskInfo.append(QString(storage.fileSystemType()));
    sm_localInfoStruct.installHardDiskInfo.append("<br\>");
    foreach (const QStorageInfo &store, QStorageInfo::mountedVolumes())
    {
        if (store.isValid() && store.isReady())
        {
            if (!store.isReadOnly()) {
                sm_localInfoStruct.installHardDiskInfo.append("已挂载目录有：");
                sm_localInfoStruct.installHardDiskInfo.append(store.displayName());
                sm_localInfoStruct.installHardDiskInfo.append("<br\>");
            }
        }
    }
    sm_localInfoStruct.installHardDiskInfo.append("分区容量：");
    sm_localInfoStruct.installHardDiskInfo.append(QString::number(storage.bytesTotal()/1000/1000));
    sm_localInfoStruct.installHardDiskInfo.append("MB");
    sm_localInfoStruct.installHardDiskInfo.append("<br\>");
    sm_localInfoStruct.installHardDiskInfo.append("剩余容量：");
    sm_localInfoStruct.installHardDiskInfo.append(QString::number(storage.bytesAvailable()/1000/1000));
    sm_localInfoStruct.installHardDiskInfo.append("MB");
    sm_localInfoStruct.installHardDiskInfo.append("<br\>");

    hardDiskInfoReadyFlag = true;
    getDisPlayCardInfo();
}

void LocalInfo::getDisPlayCardInfo()
{
    qDebug() << "getDisPlayCardInfo函数中!";
    QString envChangeString = "export LC_ALL=C" ;
    QString displaycardString = "lshw -c display | grep -E 'configuration|product'" ;
    localInfoProcess->start("bash");
    localInfoProcess->write(envChangeString.toLocal8Bit() + '\n');
    localInfoProcess->write(displaycardString.toLocal8Bit() + '\n');
    localInfoProcess->waitForStarted();
}

void LocalInfo::readDisPlayCardInfo()
{
    qDebug() << "readDisPlayCardInfo函数中!";
    while (localInfoProcess->canReadLine())
    {
        QByteArray output = localInfoProcess->readLine();
        if(QString(output).contains("product",Qt::CaseInsensitive))
        {
            numOfDisplayCard++;
            QString disPlayCardName = QString(output);
            disPlayCardName = disPlayCardName.split(':').at(1);
            QString temp = QString(tr("【显卡名称】：%1").arg(disPlayCardName));
            sm_localInfoStruct.disPlayCardInfo.append(temp);
            sm_localInfoStruct.disPlayCardInfo.append(" <br\>");
        }
        if(QString(output).contains("configuration",Qt::CaseInsensitive))
        {
            QString disPlayCardDriverName = QString(output);
            disPlayCardDriverName = disPlayCardDriverName.split(':').at(1);
            QString temp = QString(tr("【显卡驱动名称】：%1").arg(disPlayCardDriverName));
            sm_localInfoStruct.disPlayCardInfo.append(temp);
            sm_localInfoStruct.disPlayCardInfo.append(" <br\>");
        }
    }

    QString temp;
    temp = QString(tr("【显卡数量】：%1 个").arg(numOfDisplayCard));
    sm_localInfoStruct.disPlayCardInfo.append("<br\>");
    sm_localInfoStruct.disPlayCardInfo.append(temp);
    sm_localInfoStruct.disPlayCardInfo.append("<br\>");

    displayCardInfoReadyFlag = true;
    disconnect(localInfoProcess,&QProcess::readyReadStandardOutput,this,&LocalInfo::readDisPlayCardInfo);
    localInfoProcess->terminate();
    localInfoProcess->waitForFinished(1000);

    connect(localInfoProcess,&QProcess::readyReadStandardOutput,this,&LocalInfo::readNetCardInfo,Qt::UniqueConnection);
    getNetCardInfo();
}
void LocalInfo::getNetCardInfo()
{
    qDebug() << "getNetCardInfo函数中!";
    QString envChangeString = "export LC_ALL=C" ;
    QString netcardString = "lspci -vvv | grep -i -E 'ethernet|kernel'" ;
    localInfoProcess->start("bash");
    localInfoProcess->write(envChangeString.toLocal8Bit() + '\n');
    localInfoProcess->write(netcardString.toLocal8Bit() + '\n');
    localInfoProcess->waitForStarted();
}
void LocalInfo::readNetCardInfo()
{
    qDebug() << "readNetCardInfo函数中!";
    QString kernel = "";
    while (localInfoProcess->canReadLine())
    {
        QByteArray output = localInfoProcess->readLine();
        if(QString(output).contains("Ethernet",Qt::CaseInsensitive))
        {
            QStringList temp = QString(output).split(':');
            QString netCardName = QString(output).split(':').at(temp.size()-1);
            sm_localInfoStruct.netCardInfo.append(" <br\>");
            sm_localInfoStruct.netCardInfo.append("【网卡名称】");
            sm_localInfoStruct.netCardInfo.append(netCardName);
            sm_localInfoStruct.netCardInfo.append(" <br\>");
        }
        if(QString(output).contains("kernel",Qt::CaseInsensitive))
        {
            kernel = QString(output).split(':').at(1);
        }
    }
    sm_localInfoStruct.netCardInfo.append("【网卡驱动名称】");
    sm_localInfoStruct.netCardInfo.append(kernel);
    sm_localInfoStruct.netCardInfo.append(" <br\>");

    netCardInfoReadyFlag = true;

    disconnect(localInfoProcess,&QProcess::readyReadStandardOutput,this,&LocalInfo::readNetCardInfo);
    localInfoProcess->terminate();
    localInfoProcess->waitForFinished(1000);
    getMACInfo();
}
void LocalInfo::getMACInfo()
{
    qDebug() << "getMACInfo函数中!";
    QList<QNetworkInterface> nets = QNetworkInterface::allInterfaces();// 获取所有网络接口列表

    int nCnt = nets.count();
    QString macAddr = "";
    for(int i = 0; i < nCnt; i ++)
    {
        // 如果此网络接口被激活并且正在运行并且不是回环地址，则就是我们需要找的Mac地址
        if(nets[i].flags().testFlag(QNetworkInterface::IsUp)
                && nets[i].flags().testFlag(QNetworkInterface::IsRunning)
                && !nets[i].flags().testFlag(QNetworkInterface::IsLoopBack))
        {
            macAddr = nets[i].hardwareAddress();
            break;
        }
    }
    sm_localInfoStruct.macInfo.append("<br\>");
    sm_localInfoStruct.macInfo.append(macAddr);
    sm_localInfoStruct.macInfo.append("<br\>");

    macInfoReadyFlag = true;

    localInfoProcess->terminate();
    localInfoProcess->waitForFinished(1000);

    connect(localInfoProcess,&QProcess::readyReadStandardOutput,this,&LocalInfo::readlspciInfo,Qt::UniqueConnection);
    getlspciInfo();

}

void LocalInfo::getlspciInfo()
{
    qDebug() << "getlspciInfo函数中!";
    QString envChangeString = "export LC_ALL=C" ;
    QString lspciString = "lspci -vvv" ;

    localInfoProcess->start("bash");
    localInfoProcess->write(envChangeString.toLocal8Bit() + '\n');
    localInfoProcess->write(lspciString.toLocal8Bit() + '\n');
    localInfoProcess->waitForStarted();
}
void LocalInfo::readlspciInfo()
{
    qDebug() << "readlspciInfo函数中!";
    while (localInfoProcess->canReadLine())
    {
        sm_localInfoStruct.lspciInfo += localInfoProcess->readLine();
    }

    lspciInfoReadyFlag = true;

    disconnect(localInfoProcess,&QProcess::readyReadStandardOutput,this,&LocalInfo::readlspciInfo);
    localInfoProcess->terminate();
    localInfoProcess->waitForFinished(1000);

    connect(localInfoProcess,&QProcess::readyReadStandardOutput,this,&LocalInfo::readdpkgInfo,Qt::UniqueConnection);
    getdpkgInfo();
}
void LocalInfo::getdpkgInfo()
{
    qDebug() << "getdpkgInfo函数中!";
    QString envChangeString = "export LC_ALL=C" ;
    QString dpkgString = "dpkg -l" ;
    localInfoProcess->start("bash");
    localInfoProcess->write(envChangeString.toLocal8Bit() + '\n');
    localInfoProcess->write(dpkgString.toLocal8Bit() + '\n');
    localInfoProcess->waitForStarted();
}
void LocalInfo::readdpkgInfo()
{
    qDebug() << "readdpkgInfo函数中!";
    while (localInfoProcess->canReadLine())
    {
        sm_localInfoStruct.dpkgInfo += localInfoProcess->readAll();
    }
    dpkgInfoReadyFlag = true;

    disconnect(localInfoProcess,&QProcess::readyReadStandardOutput,this,&LocalInfo::readdpkgInfo);
    localInfoProcess->terminate();
    localInfoProcess->waitForFinished(1000);
    readyFlag = true;
    qDebug() << "获取本机信息流程结束!";
}

LocalInfoStruct LocalInfo::getHandledLocalInfo()
{
    qDebug() << "getHandledLocalInfo!";
    return sm_localInfoStruct;
}

bool LocalInfo::getReady()
{
    if(!readyFlag)
    {
        qDebug() << "提交时未能获取完本地信息！";
        getAllInfoIntialized();
    }
    qDebug() << "提交时已经获取完本地信息！";
    return readyFlag;
}

void LocalInfo::getAllInfoIntialized()
{
    if(false == cpuInfoReadyFlag)
    {
        sm_localInfoStruct.cpuInfo = "未获取";
        qDebug() << "提交时未能获取完CPU信息！";
    }
    if(false == hardDiskInfoReadyFlag)
    {
        sm_localInfoStruct.hardDiskInfo = "未获取";
        qDebug() << "提交时未能获取完硬盘信息！";
    }
    if(false == displayCardInfoReadyFlag)
    {
        sm_localInfoStruct.disPlayCardInfo = "未获取";
        qDebug() << "提交时未能获取完显卡信息！";
    }
    if(false == netCardInfoReadyFlag)
    {
        sm_localInfoStruct.netCardInfo = "未获取";
        qDebug() << "提交时未能获取完网卡信息！";
    }
    if(false == macInfoReadyFlag)
    {
        sm_localInfoStruct.macInfo = "未获取";
        qDebug() << "提交时未能获取完mac信息！";
    }
    if(false == lspciInfoReadyFlag)
    {
        sm_localInfoStruct.lspciInfo = "未获取";
        qDebug() << "提交时未能获取完lspci信息！";
    }
    if(false == dpkgInfoReadyFlag)
    {
        sm_localInfoStruct.dpkgInfo = "未获取";
        qDebug() << "提交时未能获取完dpkg信息！";
    }
    readyFlag = true;
}
